package com.henghe.frame.mq.config.inConfig;

import com.alibaba.fastjson.JSON;
import com.henghe.frame.mq.util.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.MessageDeliveryMode;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * Description:
 * Author: LiuWenQing
 * Datetime: 2023/3/21 09:17
 */
@Service
@Slf4j
public class RabbitSendImpl implements RabbitSend{

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Override
    public void fanoutSendMsg(String exchangeName, Object message) {
        rabbitTemplate.convertAndSend(exchangeName,"", JSON.toJSONString(message));
    }

    @Override
    public void directSendMsg(String exchangeName, String routingKey, Object message) {
        rabbitTemplate.convertAndSend(exchangeName, routingKey, com.alibaba.fastjson2.JSON.toJSONString(message));
    }

    @Override
    public void topicSendMsg(String exchangeName, String routingKey, Object message) {
        rabbitTemplate.convertAndSend(exchangeName, routingKey, com.alibaba.fastjson2.JSON.toJSONString(message));
    }

    @Override
    public void delaySendMsg(String exchange, String routingKey, Object obj, Integer delayTime) {
        rabbitTemplate.convertAndSend(exchange, routingKey, com.alibaba.fastjson2.JSON.toJSONString(obj), correlationData ->{
            correlationData.getMessageProperties().setDelay(delayTime);
            return correlationData;
        });
    }

    @Override
    public void formatDelaySendMsg(String exchange, String routingKey, Object obj, String formatDelayTime) throws Exception {
        // integer 最大取值范围（对应毫秒转换天 24d）
        Integer maxTime = 2147483647;
        // 取当前时间与延时时间的差值（单位s）
        Long difference = DateUtil.dateDiff("second" ,DateUtil.strToTimestamp(formatDelayTime,
                "yyyy-MM-dd HH:mm:ss") ,DateUtil.nowTimestamp());

        // 如果设置时间 < 当前时间 手动抛出异常
        if(difference <= 0){
            throw new Exception("设置延时日期小于当前时间");
        }

        // 如果超出阈值 则手动抛出异常
        if(maxTime < difference * 1000){
            throw new Exception("设置延时日期超长");
        }

        // 转为ms
        Integer delayTime = Math.toIntExact(difference * 1000);

        log.info("延时任务时间差值（ms）: [{}]", delayTime);
        rabbitTemplate.convertAndSend(exchange, routingKey,
                com.alibaba.fastjson2.JSON.toJSONString(obj),
                message -> {
                    message.getMessageProperties().setDeliveryMode(MessageDeliveryMode.PERSISTENT);
                    message.getMessageProperties().setDelay(delayTime);   // 毫秒为单位，指定此消息的延时时长
                    return message;
                });
    }
}
